use std::path::PathBuf;

pub mod file_ext;

#[derive(clap::Parser, Debug)]
#[command(version, author, about, long_about = None)]
pub struct ZfcArgs {
    // wait scan path
    #[arg(short, long)]
    pub path: PathBuf,
    // output file path default current dir
    #[arg(short, long, default_value = "./")]
    pub output: PathBuf,

    // out put filename
    #[arg(short, long, default_value = "scan_file_list.txt")]
    pub filename: String,

    #[arg(short, long, default_value = "false")]
    pub show_log: bool,
}

// 文件元数据结构
#[derive(Debug)]
pub struct FileMeta {
    filename: String,
    length: u64,
    path: String,
    file_type: String,
}

impl FileMeta {
    pub fn serde_json(&self) -> String {
        format!(
            r#"{{"resId":"{}","filename": "{}","path": "{}","type": "{}","length": {}}}"#,
            self.filename.split_once(".").unwrap().0,
            self.filename,
            self.path,
            self.file_type,
            self.length
        )
    }
}
/// scan folder and output file list
pub fn scan_files(config: &ZfcArgs) {
    let output_file_path = config.output.join(config.filename.clone());
    let scan_path = &config.path;
    let show_log = &config.show_log;
    if !scan_path.exists() {
        eprintln!("scan path is not a exists {}", scan_path.to_str().unwrap());
        return;
    }
    if !scan_path.is_dir() {
        eprintln!("scan path is not a dir {}", scan_path.to_str().unwrap());
        return;
    }
    recursive_folder_traversal(&output_file_path, scan_path, show_log);
}

fn recursive_folder_traversal(output_file_path: &PathBuf, folder_path: &PathBuf, show_log: &bool) {
    if *show_log {
        println!("start scan {}", folder_path.to_str().unwrap());
    }
    let mut folder_files: Vec<FileMeta> = Vec::with_capacity(100);
    for entry in folder_path.read_dir().expect("Failed to read folder") {
        let entry = entry.expect("Failed to read entry");
        let entry_path = entry.path();
        if file_ext::is_hidden_file(&entry_path) {
            continue;
        }
        if entry_path.is_dir() {
            recursive_folder_traversal(output_file_path, &entry_path, show_log);
        } else {
            folder_files.push(FileMeta {
                filename: entry_path
                    .file_name()
                    .unwrap()
                    .to_str()
                    .unwrap()
                    .to_string(),
                length: entry_path.metadata().unwrap().len(),
                path: entry_path.to_str().unwrap().to_string(),
                file_type: "local".to_string(),
            })
        }
    }
    if *show_log {
        println!(
            "end scan {} find {}",
            folder_path.to_str().unwrap(),
            folder_files.len()
        );
    }

    if folder_files.is_empty() {
        return;
    }
    let lines: Vec<String> = folder_files.iter().map(FileMeta::serde_json).collect();
    file_ext::append_line_to_file(output_file_path, &lines);
}
